/*
 * @Description:
 * @Author: maxyang
 * @Date: 2022-05-16 22:29:36
 * @LastEditTime: 2022-07-10 16:43:40
 * @LastEditors: liutq
 * @Reference:
 */
package utils

import (
	"crypto/sha1"
	"fmt"
	"io"
	"math/rand"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/maxyang107/jinglan/common"
	"github.com/maxyang107/jinglan/model/user"
)

func IsIDCard(id string) bool {
	id = strings.ToUpper(id)
	if len(id) != 15 && len(id) != 18 {
		return false
	}
	r := regexp.MustCompile("(\\d{15})|(\\d{17}([0-9]|X))")
	if !r.MatchString(id) {
		return false
	}
	if len(id) == 15 {
		tm2, _ := time.Parse("01/02/2006", string([]byte(id)[8:10])+"/"+string([]byte(id)[10:12])+"/"+"19"+string([]byte(id)[6:8]))
		if tm2.Unix() <= 0 {
			return false
		}
		return true
	} else {
		tm2, _ := time.Parse("01/02/2006", string([]byte(id)[10:12])+"/"+string([]byte(id)[12:14])+"/"+string([]byte(id)[6:10]))
		if tm2.Unix() <= 0 {
			return false
		}
		// 检验18位身份证的校验码是否正确。
		// 校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
		arrInt := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
		arrCh := []string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}
		sign := 0
		for k, v := range arrInt {
			intTemp, _ := strconv.Atoi(string([]byte(id)[k : k+1]))
			sign += intTemp * v
		}
		n := sign % 11
		valNum := arrCh[n]
		if valNum != string([]byte(id)[17:18]) {
			return false
		}
		return true
	}
}

func CheckMobile(phone string) bool {
	// 匹配规则
	// ^1第一位为一
	// [345789]{1} 后接一位345789 的数字
	// \\d \d的转义 表示数字 {9} 接9位
	// $ 结束符
	regRuler := "^1[345789]{1}\\d{9}$"

	// 正则调用规则
	reg := regexp.MustCompile(regRuler)

	// 返回 MatchString 是否匹配
	return reg.MatchString(phone)

}

//定长生成随机字符串
func RandString(lenNum int) string {
	var chars = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
	str := strings.Builder{}
	length := len(chars)
	rand.Seed(time.Now().UnixNano()) //重新播种，否则值不会变
	for i := 0; i < lenNum; i++ {
		str.WriteString(chars[rand.Intn(length)])

	}
	return str.String()
}

func CreatInviteCode(lenNum int) string {
	var code string
	step := 1
	for {
		code = RandString(lenNum)
		u := user.FindUserByInviteCode(code)
		if u.ID > 0 {
			if step%5 == 0 {
				lenNum++
			}
			step++
			continue
		}
		break
	}
	return code
}

func InterfaceToUser(value interface{}) uint {
	var op uint
	switch value.(type) {
	case uint:
		op, _ = value.(uint)
	default:
		fmt.Println("unknown")
	}
	return op
}

func GetChainInfoForGoods(goodsHash string) common.GoodsChainInfo {
	var goodsChainInfo common.GoodsChainInfo
	t := sha1.New()
	io.WriteString(t, goodsHash)
	goodsChainInfo.BlockHeight = uint(time.Now().Unix())
	goodsChainInfo.CertificatHash = fmt.Sprintf("%x", t.Sum(nil))
	goodsChainInfo.CertificatId = strconv.Itoa(int(BKDRHash(goodsHash)))
	goodsChainInfo.CertificatTiime = time.Now()
	goodsChainInfo.CreateTime = time.Now()

	return goodsChainInfo
}

func BKDRHash(str string) uint64 {
	seed := uint64(131)
	hash := uint64(0)
	for i := 0; i < len(str); i++ {
		hash = (hash * seed) + uint64(str[i])
	}
	return hash & 0x7FFFFFFF
}

func FormatMobileStar(mobile string) string {
	if len(mobile) <= 10 {
		return mobile
	}
	return mobile[:3] + "****" + mobile[7:]
}
